using System;
using System.Text;
using System.Configuration;
using System.Collections.Generic;
using MeltingSnowballs.SmugMugAPI;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace SmugMugAPITests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class JSONAPITests
    {
        public JSONAPITests()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private static string APIKEY;
        private static string LOGINNAME;
        private static string LOGINPASSWORD;
        private static string LOGINID;
        private static string LOGINHASH;

        private JSONSmugMugAPI api;

        #region Additional test attributes
        // You can use the following additional attributes as you write your tests:
        //

        // Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            APIKEY = ConfigurationManager.AppSettings["SmugMugAPIKey"];
            LOGINNAME = ConfigurationManager.AppSettings["SmugMugUserName"];
            LOGINPASSWORD = ConfigurationManager.AppSettings["SmugMugPassword"];
            LOGINID = ConfigurationManager.AppSettings["SmugMugUserID"];
            LOGINHASH = ConfigurationManager.AppSettings["SmugMugPasswordHash"];
        }

        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }


        // Use TestInitialize to run code before running each test 
        [TestInitialize()]
        public void MyTestInitialize()
        {
            api = new JSONSmugMugAPI();
        }

        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        #endregion

        [TestMethod]
        public void TestLoginWithPassword()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestLoginWithPasswordInvalid()
        {
            SMLoginInfo loginInfo = api.loginWithPassword(LOGINNAME, "NotMyPassword", APIKEY);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestLoginWithHashValid()
        {
            SMLoginInfo loginInfo = api.loginWithHash(LOGINID, LOGINHASH, APIKEY);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestLoginWithHashInvalid()
        {
            SMLoginInfo loginInfo = api.loginWithHash(LOGINID, "abclzNjIDLl$qz8Qb4Ge50CmCgEODd9ol/", APIKEY);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestLoginAnonymously()
        {
            SMSessionInfo sessionInfo = api.loginAnonymously(APIKEY);
            api.logout(sessionInfo.id);
        }

        [TestMethod]
        public void TestUsersGetTree()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMUserTreeCategory[] userTree = api.getUsersTree(loginInfo.Session.id, null, false, null);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestUsersGetTreeHeavy()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMUserTreeCategory[] userTree = api.getUsersTree(loginInfo.Session.id, null, true, null);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestUsersGetTransferStats()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMAlbumStats[] transferStats = api.getUsersTransferStats(loginInfo.Session.id, 9, 2007);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestGetAlbums()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMAlbum[] albums = api.getAlbums(loginInfo.Session.id, null, false, null);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestGetAlbumsHeavy()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMAlbum[] albums = api.getAlbums(loginInfo.Session.id, null, true, null);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestGetAlbumInfo()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMAlbum[] albums = api.getAlbums(loginInfo.Session.id, null, false, null);
            SMAlbumInfo albumInfo = api.getAlbumInfo(loginInfo.Session.id, albums[0].id, null, null);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestGetAlbumStats()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMAlbum[] albums = api.getAlbums(loginInfo.Session.id, null, false, null);
            SMAlbumStats albumStats = api.getAlbumStats(loginInfo.Session.id, albums[0].id, 10, 2007, false);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestGetAlbumStatsHeavy()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMAlbum[] albums = api.getAlbums(loginInfo.Session.id, null, false, null);
            SMAlbumStats albumStats = api.getAlbumStats(loginInfo.Session.id, albums[0].id, 10, 2007, true);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestCreateAlbum()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMAlbumSettings albumSettings = new SMAlbumSettings();

            cleanupTestCategory(loginInfo.Session.id, "SmugMugAPITest");
            int categoryID = api.createCategory(loginInfo.Session.id, "SmugMugAPITest");
            int subCategoryID = api.createSubCategory(loginInfo.Session.id, "Test1", categoryID);

            albumSettings.SubCategoryID = subCategoryID;
            albumSettings.Description = "Test Album created by SmugMug.NET";
            albumSettings.Keywords = "SmugMug.Net; Test";
            api.createAlbum(loginInfo.Session.id, "SmugMug.Net Test Album", categoryID, albumSettings);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestChangeAlbumSettings()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMAlbumSettings albumSettings = new SMAlbumSettings();

            albumSettings.Description = "Test Album created by SmugMug.NET and modified.";
            albumSettings.Keywords = "SmugMug.Net; Test; NewKeywords";
            int albumID = findAlbum(loginInfo.Session.id, "SmugMug.Net Test Album");
            api.changeAlbumSettings(loginInfo.Session.id, albumID, albumSettings);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestReSortAlbum()
        {
            SMLoginInfo loginInfo = loginToSmugMug();

            int albumID = findAlbum(loginInfo.Session.id, "SmugMug.Net Test Album");
            api.reSortAlbum(loginInfo.Session.id, albumID, "FileName", "ASC");

            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestDeleteAlbum()
        {
            SMLoginInfo loginInfo = loginToSmugMug();

            int albumID = findAlbum(loginInfo.Session.id, "SmugMug.Net Test Album");
            api.deleteAlbum(loginInfo.Session.id, albumID);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestGetCategories()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMCategory[] categories = api.getCategories(loginInfo.Session.id, null, null);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestCreateCategory()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            cleanupTestCategory(loginInfo.Session.id, "TestCategory");
            int categoryID = api.createCategory(loginInfo.Session.id, "TestCategory");
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestDeleteCategory()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            cleanupTestCategory(loginInfo.Session.id, "TestCategoryToDelete");
            int categoryID = api.createCategory(loginInfo.Session.id, "TestCategoryToDelete");
            api.deleteCategory(loginInfo.Session.id, categoryID);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestRenameCategory()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            cleanupTestCategory(loginInfo.Session.id, "TestCategoryToRename");
            int categoryID = api.createCategory(loginInfo.Session.id, "TestCategoryToRename");
            api.renameCategory(loginInfo.Session.id, categoryID, "TestCategoryRenamed");
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestGetSubcategories()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            createTestSubcategories(loginInfo.Session.id);
            int categoryID = findCategory(loginInfo.Session.id, "TestCategoryForSubcategories");
            SMSubCategory[] subCategories = api.getSubCategories(loginInfo.Session.id, categoryID, null, null);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestGetAllSubcategories()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            SMSubCategories[] subCategories = api.getAllSubCategories(loginInfo.Session.id, null, null);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestCreateSubcategory()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            createTestSubcategories(loginInfo.Session.id);
            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestDeleteSubcategory()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            createTestSubcategories(loginInfo.Session.id);

            int subCategoryID = findSubcategory(loginInfo.Session.id, "TestCategoryForSubcategories", "TestSubCategory1");
            Assert.IsTrue(subCategoryID != 0);

            bool result = api.deleteSubCategory(loginInfo.Session.id, subCategoryID);
            Assert.IsTrue(result);

            api.logout(loginInfo.Session.id);
        }

        [TestMethod]
        public void TestRenameSubcategory()
        {
            SMLoginInfo loginInfo = loginToSmugMug();
            createTestSubcategories(loginInfo.Session.id);

            int subCategoryID = findSubcategory(loginInfo.Session.id, "TestCategoryForSubcategories", "TestSubCategory2");
            Assert.IsTrue(subCategoryID != 0);

            bool result = api.renameSubCategory(loginInfo.Session.id, subCategoryID, "TestSubCategory2Renamed");
            Assert.IsTrue(result);

            api.logout(loginInfo.Session.id);
        }

        private SMLoginInfo loginToSmugMug()
        {
            return api.loginWithPassword(LOGINNAME, LOGINPASSWORD, APIKEY);
        }

        private void cleanupTestCategory(string sessionID, string categoryName)
        {
            int categoryID = findCategory(sessionID, categoryName);
            if (categoryID != 0)
                api.deleteCategory(sessionID, categoryID);
        }

        private void createTestSubcategories(string sessionID)
        {
            cleanupTestCategory(sessionID, "TestCategoryForSubcategories");
            int categoryID = api.createCategory(sessionID, "TestCategoryForSubcategories");
            int subCategoryID1 = api.createSubCategory(sessionID, "TestSubCategory1", categoryID);
            int subCategoryID2 = api.createSubCategory(sessionID, "TestSubCategory2", categoryID);
        }

        private int findCategory(string sessionID, string categoryName)
        {
            int categoryID = 0;
            SMCategory[] categories = api.getCategories(sessionID, null, null);
            foreach (SMCategory category in categories)
            {
                if (category.Title == categoryName)
                {
                    categoryID = category.id;
                    break;
                }
            }
            return categoryID;
        }

        private int findSubcategory(string sessionID, string categoryName, string subCategoryName)
        {
            int subCategoryID = 0;
            int categoryID = 0;

            categoryID = findCategory(sessionID, categoryName);
            if (categoryID != 0)
            {
                SMSubCategory[] subCategories = api.getSubCategories(sessionID, categoryID, null, null);
                foreach (SMSubCategory subCategory in subCategories)
                {
                    if (subCategory.Title == subCategoryName)
                    {
                        subCategoryID = subCategory.id;
                        break;
                    }
                }
            }
            return subCategoryID;
        }

        private int findAlbum(string sessionID, string albumName)
        {
            int albumID = 0;
            SMAlbum[] albums = api.getAlbums(sessionID, null, false, null);
            foreach (SMAlbum album in albums)
            {
                if (album.Title == albumName)
                {
                    albumID = album.id;
                    break;
                }
            }
            return albumID;
        }

    }
}
